#include <fstream>
#include <iostream>
#include "testador.h"

using std::cout;
using std::endl;
using std::ifstream;
using std::ios;
using std::string;
using std::vector;

void ReadInstance(char* file_path, Instancia* inst) {
    vector<int> aux;
    ifstream infile;
    infile.open(file_path);
    int inst_1, inst_2;

    if (!inst->vec.empty()) {
      inst->vec.clear();
    }
    if (infile.is_open() && infile.good()) {

      infile >> inst->num_clusters;
      infile >> inst->num_pos_candidatos;

      int iter_1 = 1;
      while (iter_1 <= inst->num_clusters) {
          infile >> inst_1;
          aux.clear();
          aux.push_back(inst_1);
          int iter_2 = 1;
          while(iter_2 <= inst_1){
            infile >> inst_2;
            aux.push_back(inst_2);
            iter_2++;
          }
          inst->vec.push_back(aux);
          iter_1++;
      }
      infile.close();
   } else {
     cout << "Nao consegui abrir a instancia. Erro!"<< endl;
   }
}

void ReadSolution(char* file_path, Solucao* sol) {
  ifstream infile;
  infile.open(file_path);
  int posicao_selecionada;
  int conflitos;

  if (infile.is_open() && infile.good()) {
    infile >> sol->nome_inst;
    infile >> sol->total_conflitos;
    sol->num_clusters = 0;
    while (!infile.eof()) {
      infile >> posicao_selecionada;
      infile >> conflitos;
      sol->pos_candidata.push_back(posicao_selecionada);
      sol->conflitos.push_back(conflitos);
      sol->num_clusters++;
    }
    infile.close();
  } else {
    cout << "Nao consegui abrir a solucao. Erro!" << endl;
  }
}

bool VerifyInstance(const Instancia& inst) {
  if (inst.vec.size() != inst.num_clusters && inst.vec.empty()) {
    return false;
  } else {
    for (int i=0; i < inst.vec.size(); i++) {
      if (inst.vec[i][0] != inst.vec[i].size() - 1)
        return false;
    }
  }
  return true;
}

bool SolutionRepetition(const Solucao& sol) {
  for(int i = 0; i < sol.pos_candidata.size(); i++) {
    int j = i+1;
    while (j < sol.pos_candidata.size()) {
      if(sol.pos_candidata[i] != sol.pos_candidata[j]) {
        j++;
      } else {
        return false;
    }
  }
  }
  return true;
}

bool IsFeasible(const Solucao& sol, const Instancia& inst) {
  int contador_conflitos = 0;
  for (int i = 0; i < sol.pos_candidata.size(); i++) {
      if (sol.pos_candidata[i] > ((i + 1) * inst.num_pos_candidatos) ||
        sol.pos_candidata[i] < (i * inst.num_pos_candidatos)) {
        return false;
        }
      contador_conflitos += sol.conflitos[i];
  }
  if (sol.num_clusters != inst.num_clusters || contador_conflitos != sol.total_conflitos) {
    return false;
    } else {
      return true;
    }
}

void PrintResults(const Solucao& sol,const Instancia& inst) {
  cout << "A instancia " << sol.nome_inst << " c/ " << inst.num_clusters
       << " clusters e " << inst.num_pos_candidatos <<" pontos candidatos, "
       << "tem: " << sol.total_conflitos << " conflitos." << endl;
  if (!VerifyInstance(inst)){
    cout << "The instance have some problem." << endl;
  } else if (IsFeasible(sol, inst) && SolutionRepetition(sol)) {
    cout << "Is Feasible." << endl;
  } else {
    cout << "Isn't Feasible." << endl;
  }
}
